Webworkers
File: webworkers.html (click for a live demo)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>math.js | web workers</title>
</head>
<body>
<p>
In this example, a math.js parser is running in a separate
<a href="https://www.html5rocks.com/en/tutorials/workers/basics/">web worker</a>,
preventing the user interface from freezing during heavy calculations.
</p>
<p id="results"></p>
<script>
/**
* MathWorker evaluates expressions asynchronously in a web worker.
*
* Example usage:
*
* const worker = new MathWorker()
* const expr = '12 / (2.3 + 0.7)'
* worker.evaluate(expr, function (err, result) {
* console.log(err, result)
* })
*/
function MathWorker () {
this.worker = new Worker('worker.js')
this.callbacks = {}
this.seq = 0
// create a listener to receive responses from the web worker
const me = this
this.worker.addEventListener('message', function(event) {
const response = JSON.parse(event.data)
// find the callback corresponding to this response
const callback = me.callbacks[response.id]
delete me.callbacks[response.id]
// call the requests callback with the result
callback(response.err, response.result)
}, false)
}
/**
* Evaluate an expression
* @param {string} expr
* @param {Function} callback Called as callback(err, result)
*/
MathWorker.prototype.evaluate = function evaluate (expr, callback) {
// build a request,
// add an id so we can link returned responses to the right callback
const id = this.seq++
const request = {
id: id,
expr: expr
}
// queue the callback, it will be called when the worker returns the result
this.callbacks[id] = callback
// send the request to the worker
this.worker.postMessage(JSON.stringify(request))
}
// create a MathWorker
const worker = new MathWorker()
// evaluate an expression via the worker
worker.evaluate('12 / (2.3 + 0.7)', function (err, result) {
document.getElementById('results').innerHTML += 'result: ' + result + '<br>'
})
</script>
</body>
</html>
File: worker.js
importScripts('https://unpkg.com/mathjs@14.0.0/lib/browser/math.js')
// create a parser
const parser = self.math.parser()
self.addEventListener('message', function (event) {
const request = JSON.parse(event.data)
let result = null
let err = null
try {
// evaluate the expression
result = parser.evaluate(request.expr)
} catch (e) {
// return the error
err = e
}
// build a response
const response = {
id: request.id,
result: self.math.format(result),
err: err
}
// send the response back
self.postMessage(JSON.stringify(response))
}, false)